home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1985-05-30 | 15.6 KB | 446 lines |
- (************************************************************************)
- (* Requires MRI Modula2 *)
- (* From JOURNAL OF PASCAL, ADA AND MODULA2 *)
- (* *)
- (* Strlib: *)
- (* Library module to handle strings. Included is *)
- (* terminal I/O, string length, assignment, conc- *)
- (* atention, insertion, deletion, alteration and *)
- (* the ability to select portions of a string. *)
- (* *)
- (* Verson : *)
- (* 1.0 ; November 16, 83 ; Namir C. Shammas *)
- (* 1.1 ; November 21, 84 ; Walter Maner *)
- (* *)
- (************************************************************************)
-
-
- IMPLEMENTATION MODULE Strlib;
-
- FROM Terminal IMPORT WriteString,WriteLn,Write,Read;
- FROM InOut IMPORT ReadCard,WriteCard;
-
- PROCEDURE Len(Str : ARRAY OF CHAR):CARDINAL;
-
- (* Returns the length of the string *)
-
- VAR i : CARDINAL;
- Found : BOOLEAN;
- BEGIN
- i := 0; Found :=FALSE;
-
- (* Scan the string until the eos is found *)
-
- WHILE (NOT Found) AND (i <= HIGH(Str)) DO
- IF Str[i] = eos THEN Found := TRUE
- ELSE INC(i)
- END;
- END;
- RETURN i
- END Len;
-
- PROCEDURE StringIs (VAR Str1 : ARRAY OF CHAR; Str2 : ARRAY OF CHAR);
-
- (* Procedure will assign string Str2 to string Str1 *)
-
- VAR
- i,long1,long2 : CARDINAL;
- BEGIN
-
- (* Obtain the length of both strings Str1 & Str2 *)
- long1 := Len(Str1);
- long2 := Len(Str2);
-
- (* If string Str2 if too long pick up only the portion that will *)
- (* fit in string Str1. *)
- IF long2 > (HIGH(Str1)+1) THEN long2 := HIGH(Str1)+1 END;
- FOR i := 0 TO (long2-1) DO
- Str1[i] := Str2[i]
- END;
-
- (* Put the eos if string Str1 is not full to capacity *)
- IF HIGH(Str1) # (long2-1) THEN Str1[long2] := eos END;
- END StringIs;
-
- PROCEDURE ShowString(Str : ARRAY OF CHAR );
-
- (* Procedure to display a string on the console *)
-
- VAR i,long : CARDINAL;
- BEGIN
- long := Len(Str);
- FOR i := 0 TO (long-1) DO
- Write(Str[i]);
- END;
- END ShowString;
-
- PROCEDURE StringAdd (VAR Str1 : ARRAY OF CHAR; Str2 : ARRAY OF CHAR );
-
- (* Procedure to concatenate two strings such that, *)
- (* Str1 = Str1 + Str2 *)
- (* *)
- (*-----------------------------------------------------------------*)
- (* Error Handling : If Str2 will be concatenated to strign Str1 *)
- (* in as much "free space" is availble. *)
- (*-----------------------------------------------------------------*)
-
-
- VAR
- i,long1,long2, hi : CARDINAL;
- BEGIN
-
- (* Obtain the length of the strings *)
- hi := HIGH(Str1);
- long1 := Len(Str1);
- long2 := Len(Str2);
-
- (* If string Str2 if too long pick up only the portion that will *)
- (* fit in string Str1. *)
- IF (long1+long2-1) > hi THEN long2 := hi - long1 + 1 END;
- FOR i := 0 TO (long2-1) DO
- Str1[i+long1] := Str2[i]
- END;
-
- (* Put the eos if string Str1 is not full to capacity *)
- IF hi # (long1+long2-1) THEN Str1[long1+long2] := eos END;
- END StringAdd;
-
- PROCEDURE StringDelete(VAR Str : ARRAY OF CHAR ; First,Last : CARDINAL);
-
- (* Procedure to delete a portion of a string by specifying the first *)
- (* and last character by position. *)
- (* *)
- (*-------------------------------------------------------------------*)
- (* Error Handling : *)
- (* *)
- (* (1) If Fisrt is greater than the string length, string Str will *)
- (* remain intact. *)
- (* (2) If Last is graeter than the string length, string Str will *)
- (* end at position Last. *)
- (*-------------------------------------------------------------------*)
-
-
- VAR i,long : CARDINAL;
- BEGIN
- long := Len(Str);
-
- (* If the first character is greater than the string length ignore *)
- (* the Procedure altogether. *)
-
- IF First < long THEN
-
-
- IF Last >= long (* Check if the last character *)
- (* position is within limits. *)
- THEN
- Str[First] := eos
-
- ELSE (* Delete up to the last character *)
- FOR i := Last TO (long-1) DO
- Str[First+i-Last-1] := Str[i]
- END;
-
- (* Put the eos if string Str1 *)
- Str[long+First-Last-1] := eos
- END;
- END;
- END StringDelete;
-
- PROCEDURE StringPos(Str1,Str2 : ARRAY OF CHAR ; Start : CARDINAL):CARDINAL;
-
- (* Returns the position where the sub-string Str2 occurs within string *)
- (* starting at positon 'Start' Str1. *)
- (* *)
- (*---------------------------------------------------------------------*)
- (* Error Handling : *)
- (* (1) If Str2 is bigger than Str1 to begin with, then there can be *)
- (* no matching of Str2 in Str1. *)
- (* (2) If Start is greater than the length of Str1 then return zero *)
- (* as a result. *)
- (*---------------------------------------------------------------------*)
-
-
- VAR
- long1,long2,ptr1,ptr2,last : CARDINAL;
- Found : BOOLEAN;
-
- BEGIN
-
- (* Initialize and obtain string lengths *)
- IF Start = 0 THEN Start := 1 END;
- ptr1 := Start-1; ptr2 :=0; last := ptr1;
- Found := FALSE;
- long1 := Len(Str1);
- long2 := Len(Str2);
- (* Peform the function if the sub-string is indeed the smaller *)
- IF (long1 >= long2) AND (Start <= (long1-1)) THEN
- REPEAT
- IF Str1[ptr1] = Str2[ptr2]
- THEN
- IF ptr2 = 0 THEN last := ptr1 END;
- IF ptr2 = long2-1
- THEN
- Found := TRUE
- ELSE
- INC(ptr2)
- END;
- ELSE
- IF ptr2 > 0 THEN ptr1 := last; ptr2 := 0 END;
- END;
- INC(ptr1)
- UNTIL (Found = TRUE) OR (ptr1 >= long1-1);
- END;
- (* Return zero if there was no match. *)
- IF NOT Found THEN ptr1 := 0
- ELSE DEC(ptr1,long2-1)
- END;
- RETURN ptr1
- END StringPos;
-
- PROCEDURE StringLeft(VAR Str1 : ARRAY OF CHAR ;
- Str2 : ARRAY OF CHAR; Count : CARDINAL);
-
- (* Procedure will return the 'Count' leftmost characters of string *)
- (* Str2 and save the result in string Str1. *)
- (* *)
- (*-----------------------------------------------------------------*)
- (* Error Handling : *)
- (* (1) If Count = 0 then reassugn Count as 1. *)
- (* (2) If Count is greater than the string length then adjust it *)
- (* to equal the latter. *)
- (*-----------------------------------------------------------------*)
-
- VAR long : CARDINAL;
-
- BEGIN
-
- StringIs(Str1,Str2);
- long := Len(Str1) - 1;
- IF Count = 1 THEN Count := 1 END;
- IF Count > long THEN Count := long END;
- IF Count <> long THEN
- Str1[Count] := eos
- END;
- END StringLeft;
-
- PROCEDURE StringRight(VAR Str1 : ARRAY OF CHAR ;
- Str2 : ARRAY OF CHAR; Count : CARDINAL);
-
- (* Procedure will return the 'Count' rightmost characters of string *)
- (* Str2 and save the result in string Str1. *)
- (* *)
- (*------------------------------------------------------------------*)
- (* Error Handling : If Count is zero or greater than the string *)
- (* length then string Str1 will be an exact copy of Str2. *)
- (*------------------------------------------------------------------*)
-
- VAR i,long ,used: CARDINAL;
- BEGIN
-
- (* Copy string Str2 into string Str1 and obtain its length. *)
- StringIs(Str1,Str2);
- long := Len(Str1);
- IF (Count <= long) AND (Count # 0) THEN
-
- (* Obtain the first character position to relocate string Str1. *)
- used := long - Count;
- FOR i := 0 TO (Count-1) DO
- Str1[i] := Str1[used+i]
- END;
- Str1[Count] := eos
- END;
- END StringRight;
-
- PROCEDURE StringMid(VAR Str1 : ARRAY OF CHAR ;
- Str2 : ARRAY OF CHAR; Start, Count : CARDINAL);
-
- (* Procedure will copy the portion of string Str2 from the character *)
- (* position 'Start' and for 'Count' characters into string Str1. *)
- (* *)
- (*---------------------------------------------------------------------*)
- (* Error Handling : If the sum of Start and Count is greater than the *)
- (* string length then the resulting string Str1 will be identical to *)
- (* string Str2. *)
- (*---------------------------------------------------------------------*)
-
- VAR i,long : CARDINAL;
- BEGIN
- StringIs(Str1,Str2);
- IF Start > 0 THEN DEC(Start) END;
- long := Len(Str1);
- IF (Start + Count) <= long THEN
- FOR i := Start TO (Start+Count-1) DO
- Str1[i-Start] := Str1[i]
- END;
- IF HIGH(Str1) # Count THEN Str1[Count] := eos END;
- END;
- END StringMid;
-
- PROCEDURE StringRemove(VAR Str1 : ARRAY OF CHAR; Str2 : ARRAY OF CHAR);
-
- (* Procedure to remove all occurences of sub-string Str2 from Str1. *)
-
- VAR
- i,long1,long2,ptr,position,move,high : CARDINAL;
-
- BEGIN
- high := HIGH(Str1);
- long1 := Len(Str1);
- long2 := Len(Str2);
- ptr := 1;
- REPEAT
- position := StringPos(Str1,Str2,ptr);
- IF position # 0 THEN (* Shift characters to overwrite Str2 *)
- ptr := position - 1;
- FOR i := (ptr+long2) TO (long1-1) DO
- Str1[i-long2] := Str1[i]
- END;
- DEC(long1,long2);
- Str1[long1] := eos;
- END;
- UNTIL position = 0; (* Cannot find any more sub-strings *)
- END StringRemove;
-
- PROCEDURE StringInsert(VAR Str1 : ARRAY OF CHAR; Str2 : ARRAY OF CHAR;
- Start : CARDINAL);
-
- (* Procedure will insert string Str2 in Str1 at the character *)
- (* position 'Start' of string Str1. *)
- (* *)
- (*------------------------------------------------------------*)
- (* Error Handling : If there no room for string Str2 to be *)
- (* inserted entirely string Str1 will remain intact. *)
- (*------------------------------------------------------------*)
-
- VAR
- i,long1,long2 : CARDINAL;
- BEGIN
- DEC(Start);
- long1 := Len(Str1);
- long2 := Len(Str2);
- IF (long1+long2-1) <= HIGH(Str1) THEN
-
- (* Relocate portions of Str1 to make way for string Str2. *)
- FOR i := (long1-1) TO Start BY -1 DO
- Str1[i+long2] := Str1[i]
- END;
-
- (* Copy string Str2 into the reserved loaction of string Str1. *)
- FOR i := Start TO (Start+long2-1) DO
- Str1[i] := Str2[i-Start]
- END;
- INC(long1,long2);
- IF (long1-1) < HIGH(Str1) THEN Str1[long1] := eos END;
- END;
- END StringInsert;
-
- PROCEDURE StringReplace(VAR Str1 : ARRAY OF CHAR; Str2,Str3 : ARRAY OF CHAR);
-
- (* Procedure will replace all occurences of sub-string Str2, in string *)
- (* Str1, by sub-string Str3. *)
-
- VAR
- i,long1,long2,long3,ptr,pos,Stringhigh : CARDINAL;
- BEGIN
- long1 := Len(Str1);
- long2 := Len(Str2);
- long3 := Len(Str3);
- ptr := 1;
- Stringhigh := HIGH(Str1)+1;
- REPEAT
- pos := StringPos(Str1,Str2,ptr);
- IF pos # 0 THEN
- ptr := pos;
- StringDelete(Str1,ptr,(ptr+long2-1));
- StringInsert(Str1,Str3,ptr);
- long1 := long1 - long2 + long3;
- IF long1 = Stringhigh THEN pos :=0
- ELSE Str1[long1] := eos
- END;
- END;
- UNTIL pos = 0;
- END StringReplace;
-
- PROCEDURE StringChange(VAR Str1 : ARRAY OF CHAR; Str2,Str3 : ARRAY OF CHAR;
- Start,Repeat:CARDINAL);
-
- (* Procedure will replace sub-string Str2 with Str3 in string Str1 *)
- (* start at character position 'Start' and for 'Repeat' times. *)
-
- VAR
- i,long1,long2,long3,ptr,pos,Stringhigh : CARDINAL;
- BEGIN
- long1 := Len(Str1);
- long2 := Len(Str2);
- long3 := Len(Str3);
- ptr := Start;
- Stringhigh := HIGH(Str1)+1;
- REPEAT
- pos := StringPos(Str1,Str2,ptr);
- IF pos # 0 THEN
- ptr := pos;
- StringDelete(Str1,ptr,(ptr+long2-1));
- StringInsert(Str1,Str3,ptr);
- long1 := long1 - long2 + long3;
- IF long1 = Stringhigh THEN pos :=0
- ELSE Str1[long1] := eos
- END;
- DEC(Repeat);
- END;
- UNTIL pos*Repeat = 0;
- END StringChange;
-
- PROCEDURE StringAlter(VAR Str1 : ARRAY OF CHAR; Str2 : ARRAY OF CHAR;
- Start : CARDINAL);
-
- (* Procedure will overwrite string Str1 with sub-string Str2 starting *)
- (* at position 'Start'. *)
- (* *)
- (*--------------------------------------------------------------------*)
- (* Error Handling : If there is no room for string Str2 to fit in *)
- (* its entirey string Str1 will remain intact. *)
- (*--------------------------------------------------------------------*)
-
- VAR
- i,long,ptr : CARDINAL;
- BEGIN
- DEC(Start);
- long := Len(Str2);
- IF (Start+long-1) <= HIGH(Str1) THEN
- FOR i := Start TO (Start+long-1) DO
- Str1[i] := Str2[i-Start]
- END;
- END;
- END StringAlter;
-
- PROCEDURE InputString (VAR Str : ARRAY OF CHAR);
-
- (* Read string from the keyboard. *)
-
- VAR
- i,high : CARDINAL;
- ch : CHAR;
- BEGIN
- high := HIGH(Str);
- i := 0;
- REPEAT
- Read(ch);
- Write(ch);
- IF ch # CHAR(177C)
- THEN
- Str[i] := ch;
- INC(i)
- ELSE
- Write(' ');
- Write(ch);
- IF i > 0 THEN DEC(i) END;
- END;
- UNTIL (ch = CHAR(36C)) OR (i > high);
- IF i <= high THEN
- DEC(i);
- Str[i] := eos
- END;
- END InputString;
-
- END Strlib.